package morning.cat.demo.config;

import com.jfinal.config.*;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.template.Engine;
import morning.cat.demo.config.route.AdminRoutes;
import morning.cat.demo.config.route.FrontRoutes;
import morning.cat.demo.controller.HelloController;
import morning.cat.demo.entity.User;
import morning.cat.demo.handler.ResourceHandler;
import morning.cat.demo.interceptor.AuthInterceptor;
import morning.cat.demo.interceptor.FrontInterceptor;

public class DemoConfig extends JFinalConfig {

    /**
     * 此方法用来配置JFinal常量值，如开发模式常量devMode的配置
     *
     * @param constants
     */
    @Override
    public void configConstant(Constants constants) {
        constants.setDevMode(true);
    }

    /**
     * 此方法用来配置访问路由
     *
     * @param routes
     */
    @Override
    public void configRoute(Routes routes) {
        // 用于为该Routes 内部的所有Controller设置视图渲染时的基础路径，该基础路径与Routes.add(…, viewPath)方法传入的viewPath以及 Controller.render(view) 方法传入的 view 参数联合组成最终的视图路径
        // finalView = baseViewPath + viewPath + view
        // 注意：当view以 “/” 字符打头时表示绝对路径，baseViewPath 与 viewPath 将被忽略。
        // routes.setBaseViewPath("/view");

        // routes.addInterceptor(new FrontInterceptor());

        //routes.add("/hello", HelloController.class);

        // 推荐 对大规模团队开发十分有用
        routes.add(new FrontRoutes());
        routes.add(new AdminRoutes());
    }

    /**
     * 用来配置Template Engine
     *
     * @param engine
     */
    @Override
    public void configEngine(Engine engine) {
//        engine.addSharedFunction("/view/common/layout.html");
//        engine.addSharedFunction("/view/common/paginate.html");
//        engine.addSharedFunction("/view/admin/common/layout.html");
    }

    /**
     * 此方法用来配置JFinal的Plugin
     *
     * @param plugins
     */
    @Override
    public void configPlugin(Plugins plugins) {

        PropKit.use("mysql/config.properties");
        String driverClass = PropKit.get("jdbc.driver");
        String url = PropKit.get("jdbc.url");

        // Prop 配合用法
        Prop prop = PropKit.use("mysql/config.properties");
        String username = prop.get("jdbc.username");
        String password = prop.get("jdbc.password");

        /**
         * 如下代码配置了Druid数据库连接池插件与ActiveRecord数据库访问插件。通过以下的配置，可以在应用中使用ActiveRecord非常方便地操作数据库。
         */
        DruidPlugin druidPlugin = new DruidPlugin(url, username, password, driverClass);
        plugins.add(druidPlugin);

        /**
         * ActiveRecord 是 JFinal 最核心的组成部分之一，通过 ActiveRecord 来操作数据库，将极大地减少代码量，极大地提升开发效率。
         * ActiveRecord 模式的核心是：一个 Model 对象唯一对应数据库表中的一条记录，而对应关系依靠的是数据库表的主键值。
         * ActiveRecordPlugin 作为JFinal的Plugin而存在的
         */
        ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(druidPlugin);
        activeRecordPlugin.addMapping("user", User.class);
        plugins.add(activeRecordPlugin);

        /**
         * EhCachePlugin是作为JFinal的Plugin而存在的，所以使用时需要在JFinalConfig中配置EhCachePlugin
         */
        plugins.add(new EhCachePlugin());
    }

    /**
     * 此方法用来配置JFinal的全局拦截器，全局拦截器将拦截所有 action 请求，除非使用@Clear在Controller中清除，如下代码配置了名为AuthInterceptor的拦截器。
     *
     * @param interceptors
     */
    @Override
    public void configInterceptor(Interceptors interceptors) {
        // JFinal 的 Interceptor 非常类似于 Struts2，但使用起来更方便，
        // Interceptor 配置粒度分为 Global、Inject、Class、Method四个层次，其中以上代码配置粒度为全局。
        // Inject、Class与Method级的Interceptor配置将在后续章节中详细介绍。
        interceptors.add(new AuthInterceptor());
    }

    /**
     * 此方法用来配置JFinal的Handler
     *
     * @param handlers
     */
    @Override
    public void configHandler(Handlers handlers) {
        //如下代码配置了名为ResourceHandler的处理器，Handler可以接管所有web请求，并对应用拥有完全的控制权，可以很方便地实现更高层的功能性扩展。
//        handlers.add(new ResourceHandler());
    }


    // 系统启动完成后回调
    @Override
    public void afterJFinalStart() {
        System.out.println("系统启动完成后回调");
    }

    // 系统关闭之前回调
    @Override
    public void beforeJFinalStop() {
        System.out.println("系统关闭之前回调");
    }
}
